!% +language_name=3English Constant Story "William Tell"; Constant Headline "^A Simple Inform example ^by Roger Firth and Sonja Kesserich ^Ported to Triform by Nathan Schwartzman^"; Constant MAX_SCORE = 4; Include "3Parser"; Include "3Verblib"; ! When creating a new class, it's a good idea to have it inherit ! from the Thing class as well. This can save headaches down the ! road. ! ! Whereas the original version of this game had its own Room class, ! Triform already provides one, so here there is none. Also, note that ! we make the new Prop class also belong to the Thing class, since all ! game objects must be Things. Class Prop class Thing, with react_before [; Examine: rfalse; default: if (noun ~= self) rfalse; print_ret "You don't need to worry about ", (the) self, "."; ], has scenery; Class Furniture class Container, with react_before [; TaKe, Pull, Push, PushDir: if (noun ~= self) rfalse; print_ret (The) self, " is too heavy for that."; ], ontop_capacity 4, has static; Class Arrow class Thing, with name "arrow" "arrows//p", article "an", plural "arrows", description "Just like all your other arrows -- sharp and true.", react_before [; if (noun ~= self) rfalse; Drop: "Much too dangerous to leave lying around."; Give: "Much too valuable to just give away."; ]; Room street "A street in Altdorf" with description [; print "The narrow street runs north towards the town square. Local folk are pouring into the town towards the gate to the south, shouting greetings, offering produce for sale, exchanging news, enquiring with exaggerated disbelief about the prices of the goods displayed by merchants whose stalls make progress even more difficult.^"; if (self.visited == false) print "^~Stay close to me, son,~ you say, ~or you'll get lost among all these people.~^"; ], n_to below_square, s_to "The crowd, pressing north towards the square, makes that impossible.", has light; Prop -> "south gate" with name "gate", adjective 'south' 'southern' 'wood' 'wooden', description "The large wooden gate in the town walls is wide open."; Prop -> "assorted stalls" with name "stalls", adjective 'assorted', description "Food, clothing, mountain gear; the usual stuff.", found_in street below_square, has pluralname; ! All people should inherit from the Person class, even simple ones ! like these merchants and local folk. Prop -> "merchants" class Person, with name "merchants" "merchant" "trader" "traders", description "A few crooks, but mostly decent traders touting their wares with raucous overstatement.", found_in street below_square, has pluralname; Prop "local people" class Person, with name "people" "folk" "crowd", adjective 'local', description "Mountain folk, just like yourself.", found_in true, has pluralname; Room below_square "Further along the street" with description "People are still pushing and shoving their way from the southern gate towards the town square, just a little farther north. You recognise the owner of a fruit and vegetable stall.", n_to south_square, s_to street, has light; Furniture -> stall "fruit and vegetable stall" with name "stall" "table", adjective 'fruit' 'and' 'vegetable' 'veg' 'veggie' 'veggies' 'vegetables', description "It's really only a small table, with a big heap of potatoes, some carrots and turnips, and a few apples.", before [; Search: <>; ], has scenery; Prop ->-> potatoes "potatoes" with name "potato" "potatoes" "spuds", description "Must be a particularly early variety... by some 300 years!", has pluralname; Prop ->-> vegetables "fruit and vegetables" with name "carrots" "turnip" "turnips" "apples" "vegetables", description "Fine locally grown produce.", has pluralname; ! The -visited- attribute of the standard library doesn't exist in Triform; ! instead the Room class provides a (visited) variable. ! So, in Helga's (initial) routine, we have to examine below_square.visited. Person -> stallholder "Helga" with name "Helga" "stallholder" "greengrocer" "monger" "shopkeeper" "merchant" "owner" "dress" "scarf" "headscarf", description "Helga is a plump, cheerful woman, concealed beneath a shapeless dress and a spotted headscarf.", initial [; print "Helga pauses from sorting potatoes to give you a cheery wave.^"; if (below_square.visited == false) { Move(apple, player); print "^~Hello, Wilhelm, it's a fine day for trade! Is this young Walter? My, how he's grown. Here's an apple for him -- tell him to mind that scabby part, but the rest's good enough. How's Frau Tell? Give her my best wishes.~^"; } ], times_spoken_to 0, life [; Kiss: "~Ooh, you saucy thing!~"; Talk: self.times_spoken_to = self.times_spoken_to + 1; switch (self.times_spoken_to) { 1: score = score + 1; "You warmly thank Helga for the apple."; 2: score = score + 1; "~See you again soon.~"; default: rfalse; } ], has female proper; Room south_square "South side of the square" with description "The narrow street to the south has opened into the town square, and resumes at the far side of this cobbled meeting place. To continue along the street towards your destination -- Johansson's tannery -- you must walk north across the square, in the middle of which you see Gessler's hat set on that loathsome pole. If you go on, there's no way you can avoid passing it. Imperial soldiers jostle rudely through the throng, pushing, kicking, and swearing loudly.", n_to mid_square, s_to below_square, has light; Prop "pole" with name "pole", adjective 'wooden' 'wood' 'pole', description "You're too far away to see any detail.", found_in south_square north_square; Prop "Gessler's soldiers" class Person, with name "soldier" "soldiers", description "They're uncouth, violent men, not from around here.", before [; FireAt: "You're outnumbered many times over."; Talk: "Such scum are beneath your contempt."; ], found_in south_square mid_square north_square marketplace, has pluralname; Room mid_square "Middle of the square" with description "There is less of a crush in the middle of the square; most people prefer to keep as far away as possible from the pole which towers here, topped with that absurd ceremonial hat. A group of soldiers stands nearby, watching everyone who passes.", n_to north_square, s_to south_square, warnings_count 0, before [; Go: if (noun == s_obj) { self.warnings_count = 0; pole.has_been_saluted = false; } if (noun == n_obj) { if (pole.has_been_saluted == true) { print "^~Be sure to have a nice day.~^"; rfalse; } else { self.warnings_count = self.warnings_count + 1; switch (self.warnings_count) { 1: "A soldier bars your way. ^^ ~Oi, you lofty. Forgot yer manners, didn't you? How's about a nice salute to the vogt's hat?~"; 2: "^~I know you, Tell, yer a troublemaker, ain't you? Well, we don't want no bovver here, so just be a good boy and salute the friggin' hat. Do it now: I ain't gonna ask you again...~"; default: print "^^~OK, "; style underline; print "Herr"; style roman; print " Tell, now you're in real trouble. I asked you nice, but you was too proud and too stupid. I think it's time that the vogt had a little word with you.~ ^^ And with that the soldiers seize you and Walter and, while the sergeant hurries off to fetch Gessler, the rest drag you roughly towards the old lime tree growing in the marketplace.^"; ! In a standard library game, we could just call "move apple to son". But since ! things are a bit more complicated in Triform, we need Move(apple, son). ! ! And remember from Heidi that PlayerTo(marketplace) is replaced by ! Move(player, marketplace, 1). Move(apple, son); Move(player, marketplace, 1); rtrue; } } } ], has light; Furniture -> pole "wooden pole" with name "pole" "pine", adjective 'wood' 'wooden', description "The pole, the trunk of a small pine some inches in diameter, stands about nine or ten feet high. Set carefully on top is Gessler's ludicrous black and red leather hat, with a widely curving brim and a cluster of dyed goose feathers.", has_been_saluted false, before [; Salute: self.has_been_saluted = true; "You salute the hat on the pole. ^^ ~Why, thank you,~ sneers the soldier."; ], has scenery; Room north_square "North side of the square" with description "A narrow street leads north from the cobbled square. In its centre, a little south, you catch a last glimpse of the pole and hat.", n_to [; gameover = 3; "With Walter at our side, you leave the square by the north street, heading for Johansson's tannery."; ], s_to "You hardly feel like going through all that again.", has light; Room marketplace "Near the marketplace" with description "Altdorf's marketplace, close by the town square, has been hastily cleared of stalls. A troop of soldiers has pushed back the crowd to leave a clear space in front of the lime tree, which has been growing here for as long as anybody can remember. Usually it provides some shade for the old men of the town, who gather below to gossip, watch the girls, and play cards. Today, though, it stands alone... apart, that is, from Walter, who has been lashed to the trunk. About forty yards away, you are constrained by the vogt's men.", cant_go "And what? Leave your son tied up here?", has light; Thing -> tree "lime tree" with name "tree", adjective 'lime', description "It's just a large tree.", before [; FireAt: if(BowOrArrow(second)) { gameover = 3; "Your hand shakes a little, and your arrow flies high, hitting the trunk a few inches above Walter's head."; } rtrue; ], has scenery; Person -> governor "governor" with name "governor" "vogt" "Hermann" "Gessler", description "Short, stout with a thin, mean face, Gessler relishes the power he holds over the local community.", initial [; print "Gessler is watching from a safe distance, a sneer on his face.^"; if (marketplace.visited == false) { "^~It appears that you need to be taught a lesson, fool. Nobody shall pass through the square without paying homage to his Imperial Highness Albert; nobody, hear me? I could have you beheaded for treason, but I'm going to be lenient. If you should be so foolish again, you can expect no mercy, but this time, I'll let you go free... just as soon as you demonstrate your archery skills by hitting this apple from where you stand. That shouldn't prove too difficult; here, sergeant, catch. Balance it on the little bastard's head.~"; } ], life [; Talk: "You cannot bring yourself to do that."; ], before [; FireAt: if (BowOrArrow(second)) { gameover = 3; "Before the startled soldiers can react, you turn and fire at Gessler; your arrow pierces his heart, and he dies messily. A gasp, and then a cheer, goes up from the crowd."; } rtrue; ], has male proper; Thing bow "bow" with name "bow", description "Your trusty yew bow, strung with flax.", before [; Drop, Give: "You're never without your trusty bow."; ], has clothing; Container quiver "quiver" with name "quiver", description "Made of goatskin, it usually hangs over your left shoulder.", before [; Drop, Give: "But it was a present from Hedwig, your wife."; ], inside_capacity 10, has clothing; Arrow -> "arrow"; Arrow -> "arrow"; Arrow -> "arrow"; Person son "your son" with name "son" "boy" "lad" "Walter", description [; if (self in marketplace) "He stares at you, trying to appear brave and remain still. His arms are pulled back and tied behind the trunk, and the apple nestles amid his blonde hair."; else "A quiet, blonde lad of eight summers, he's fast learning the ways of mountain folk."; ], life [; Give: score = score + 1; Move(noun, self); "~Thank you, Papa.~"; ! "if (self in marketplace)" is sufficient for this game, since Walter ! can't enter any Containers. In a more complicated game, it would be ! much safer to use "if (self.location == marketplace)". See the ! apple's (description) property below. Talk: if (self in marketplace) "~Stay calm, my son, and trust in God.~"; else "You point out a few interesting sights."; ], before [; Examine, Listen, Salute, Talk: rfalse; FireAt: if (self in marketplace) { gameover = 3; "Oops! Surely you didn't mean to do that?"; } else rfalse; default: if (self in marketplace) "The guards won't permit it."; else rfalse; ], daemon [; if (self notin player.location) Move(self, player.location); ], has male proper scenery transparent; ! We test the apple's (location) property, and not simply whether it is ! "in" the marketplace, because "location" is distinct from the immediate ! possessor. Thing apple "apple" with name "apple", description [; if (self.location == marketplace) "At this distance you can barely see it."; else "The apple is blotchy green and brown."; ], before [; Drop: "An apple is worth quite a bit -- better hang on to it."; Eat: "Helga intended it for Walter."; FireAt: if (self.location == marketplace) { if (BowOrArrow(second)) { score = score + 1; gameover = 2; "Slowly and steadily, you place an arrow in the bow, draw back the string, and take aim with more care than ever in your life. Holding your breath, unblinking, fearful, you release the arrow. It flies across the square towards your son, and drives the apple against the trunk of the tree. The crowd erupts with joy; Gessler looks distinctly disappointed."; } rtrue; } else rfalse; ]; [ Initialise; player.location = street; Move(son, street); StartDaemon(son); Move(bow, player); Move(quiver, player); give quiver worn; player.description = "You wear the traditional garb of a Swiss mountaineer."; print_ret "^^ The place: Altdorf, in the Swiss canton of Uri. The year is 1307, at which time Switzerland is under rule by the Emperor Albert of Habsburg. His local governor -- the vogt -- is the bullying Hermann Gessler, who has placed his hat atop a wooden pole in the centre of the town square; everybody who passes through the the square must bow to this hated symbol of imperial might. ^^ You have come from your cottage high in the mountains, accompanied by your younger son, to purchase provisions. You are a proud and independent man, a hunter and guide, renowned both for your skill as an archer, and, perhaps unwisely (for his soldiers are everywhere) for failing to hide your dislike of the vogt. ^^ It's market-day: the town is packed with people from the surrounding villages and settlements.^"; ]; [ DeathMessage; "You have screwed up a favourite folk story."; ]; Include "3Grammar"; [ TalkSub; if (noun == player) "Nothing you hear surprises you."; if (RunLife(noun, ##Talk) ~= false) return; "At the moment, you can't think of anything to say."; ]; Verb 'talk' 't//' 'converse' 'chat' 'gossip' * 'to'/'with' creature -> Talk * creature -> Talk; [ BowOrArrow o; if (o == bow or nothing || o ofclass Arrow) rtrue; print "That's an unlikely weapon, isn't it?"; rfalse; ]; [ FireAtSub; if (noun == nothing) "What, just fire off at nothing?"; if (BowOrArrow(second)) "Pretty dangerous, don't you think?"; ]; Verb 'fire' 'shoot' 'aim' * -> FireAt * noun -> FireAt * 'at' noun -> FireAt * 'at' noun 'with' noun -> FireAt * noun 'with' noun -> FireAt * noun 'at' noun -> FireAt reverse; [ SaluteSub; if (noun ofclass Person) print_ret (The) noun, " acknowledges you."; print_ret (The) noun, " takes no notice."; ]; Verb 'bow' 'kowtow' 'nod' 'genuflect' * 'at'/'to'/'towards' noun -> Salute; Verb 'salute' 'greet' 'acknowledge' * noun -> Salute; Extend 'give' * 'homage' 'to' noun -> Salute; Extend 'wave' * 'at' noun -> Salute; end;